import difflib, logging

class Diff:
    ADD = 1
    REMOVE = 0
    ACTION = ['REMOVE', 'ADD']
    
    def __init__(self, old_text, new_text, old_annotation, new_annotation):
        """
        old text - original text without zero-th '\n'
        new text - new text
        old annotation - annotation of blip [ {'name', 'value', 'range': {'start', 'end'}} ] (blip.annotation.serialize())
        new annotation - new annotation in the same format 
        """
        diff = difflib.Differ()
        self.old_text = old_text.splitlines()
        self.new_text = new_text.splitlines()
        self.new_annotation = new_annotation
        self.cmp = list(diff.compare(self.new_text, self.old_text))
    
  
    def get_text_position(self, splited_text, line_number):
        position = 0
        if line_number == 0:
            line_number = len(splited_text)
        for l in splited_text[:line_number]:
            position += len(l) + 1
        return position
    
    def get_diff_list(self):
        old_text_line_number = new_text_line_number = -1
        change_list = []
        for line in self.cmp[::-1]:
            sign = line[:2]
            if sign == '  ':
                old_text_line_number += -1
                new_text_line_number += -1
            elif sign == '+ ':
                begin = self.get_text_position(self.old_text, old_text_line_number)
                end = begin + len(line) - 1
                change_list.append({"action": Diff.REMOVE, 
                                    "range": (begin, end), 
                                    "text": u'\n' + line[2:], 
                                    "annotation": None}) #IMPLEMENT THIS
                old_text_line_number += -1
            elif sign == '- ':
                begin = self.get_text_position(self.old_text, old_text_line_number + 1)
                end = begin + len(line) - 1
                change_list.append({"action": Diff.ADD, 
                                    "range": (begin, end), 
                                    "text": u'\n' + line[2:],
                                    "annotation": self.get_line_annotation(self.get_text_position(self.new_text, 
                                                                           new_text_line_number) + len(line) - 2)})
                new_text_line_number += -1
        return change_list
    
    def get_line_annotation(self, position):
        """
        gets annotation of line No.line_number of new text
        """
        annotation = []
        for ann in self.new_annotation:
            if ann['range']['start'] <= position and position <= ann['range']['end']:
                annotation.append((ann['name'], ann['value']))
        return annotation
        
    def get_annotation_diff(self):
        pass